﻿/// <reference path="../../../../SIR.Web/scripts/_references.js" />
/// <reference path="../../../../SIR.Web/scripts/jquery-1.9.1.js" />
/// <reference path="../../../../SIR.Web/scripts/angular.js" />
/// <reference path="../../../../SIR.Web/scripts/angular-mocks.js" />

/// <reference path="../../../../SIR.Web/app/app.js" />
/// <reference path="../../../../SIR.Web/app/common/common.js" />
/// <reference path="../../../../SIR.Web.Tests/JavaScript/sir-mock.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/authenticate.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/services/auth-service.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/controllers/user-control-panel-controller.js" />
/// <reference path="../../../../SIR.Web/app/user/user.js" />
/// <reference path="../../../../SIR.Web/app/user/controllers/user-profile-edit-controller.js" />

describe('User Control Panel Controller - Log In:', function () { 
    'use strict';
	// initialize variables and modules
    var scope, location, controller, rootScope, $httpBackend, notifyService;

    beforeEach(module('ui.router'));
    beforeEach(module('app.common'));
    beforeEach(module('app.authenticate'));
    beforeEach(module('app.user'));

    beforeEach(inject(function ($injector, $controller, $rootScope, authService, notify) {
		// set variable values
    	notifyService = notify;
    	$httpBackend = $injector.get('$httpBackend');
    	rootScope = $rootScope;
    	scope = $rootScope.$new();

    	$httpBackend.expectPOST('/api/Authentication/LogIn').respond({ Successful: false, Content: null, Message: '' });
    	controller = $controller('ControlPanelController', { $scope: scope, $state: {}, authService: authService });
    	$httpBackend.flush();
       
    	// Log In before each test
    	spyOn(controller, 'handleLogInReply').andCallThrough();
    	spyOn(controller, 'showLoggedInState');
    	$httpBackend.expectPOST('/api/Authentication/LogIn').respond({ Successful: true, Content: {}, Message: 'Authentication Successful' });
    	scope.model.email = 'email';
    	scope.model.password = 'password';
    	scope.logIn();
    	scope.$digest();
    	$httpBackend.flush();
		// expect that the log in was successful
    	expect(controller.handleLogInReply).toHaveBeenCalled();
    	expect(controller.showLoggedInState).toHaveBeenCalled();
    	expect(scope.user).toNotBe(null);
    	expect(scope.user).toNotBe(undefined);
    	expect(scope.model.email).toBe('');
    	expect(scope.model.password).toBe('');

		// create scope and controller
    	scope = $rootScope.$new();
    	controller = $controller('UserProfileEditController', { $scope: scope, $state: {}, authService: authService });

		// spy on methods
    	spyOn(controller, 'handleSubmitChangePassword').andCallThrough();
    	spyOn(notifyService, 'success').andCallThrough();
    	spyOn(notifyService, 'warning').andCallThrough();
    	spyOn(notifyService, 'error').andCallThrough();
    }));

    afterEach(function () {
		// verify all web calls were satisfied
    	$httpBackend.verifyNoOutstandingExpectation();
    	$httpBackend.verifyNoOutstandingRequest();
    });

    describe('Controller - User Change Password (Total: 3)', function () {
    	it('[1] Produce \'Invalid current password\' message when user enters a valid email and an invalid current password', function () {
    		inject(function () {
    			// Expect change password request, return successful response
    			$httpBackend.expectPOST('/api/Authentication/ChangePassword').respond({ Successful: false, Content: {}, Message: 'Invalid current password' });
    			// Set model values to pass validation
    			scope.model.currentPassword = 'old password';
    			scope.model.newPassword = 'new password';
    			scope.model.confirmNewPassword = 'new password';
    			scope.submitChangePassword();
    			$httpBackend.flush();
    			rootScope.$apply();
    		});
    		// Check methods were called, values were cleared, and correct notify method was called with the message
    		expect(controller.handleSubmitChangePassword).toHaveBeenCalled();
    		expect(notifyService.error).toHaveBeenCalledWith('Invalid current password');
    		expect(scope.model.newPassword).toBe('');
    		expect(scope.model.confirmNewPassword).toBe('');
    		expect(scope.model.currentPassword).toBe('');
    	});

    	it('[2] Produce \'Invalid new password\' message when user enters a valid email, a valid current password, and an invalid new password', function () {
    		inject(function () {
    			// Expect change password request, return successful response
    			$httpBackend.expectPOST('/api/Authentication/ChangePassword').respond({ Successful: false, Content: {}, Message: 'Invalid new password' });
    			// Set model values to pass validation
    			scope.model.currentPassword = 'old password';
    			scope.model.newPassword = 'new password';
    			scope.model.confirmNewPassword = 'new password';
    			scope.submitChangePassword();
    			$httpBackend.flush();
    			rootScope.$apply();
    		});
    		// Check methods were called, values were cleared, and correct notify method was called with the message
    		expect(controller.handleSubmitChangePassword).toHaveBeenCalled();
    		expect(notifyService.error).toHaveBeenCalledWith('Invalid new password');
    		expect(scope.model.newPassword).toBe('');
    		expect(scope.model.confirmNewPassword).toBe('');
    		expect(scope.model.currentPassword).toBe('');
    	});

    	it('[3] Produce \'Password successfully changed\' message when user enters a valid email, a valid current password, and a valid new password', function () {
    		inject(function () {
				// Expect change password request, return successful response
    			$httpBackend.expectPOST('/api/Authentication/ChangePassword').respond({ Successful: true, Content: {}, Message: 'Password successfully changed' });
				// Set model values to pass validation
    			scope.model.currentPassword = 'old password';
    			scope.model.newPassword = 'new password';
    			scope.model.confirmNewPassword = 'new password';
				// submit change password
    			scope.submitChangePassword();
    			$httpBackend.flush();
    			rootScope.$apply();
    		});
			// Check methods were called, values were cleared, and correct notify method was called with the message
    		expect(controller.handleSubmitChangePassword).toHaveBeenCalled();
    		expect(notifyService.success).toHaveBeenCalledWith('Password successfully changed');
    		expect(scope.model.newPassword).toBe('');
    		expect(scope.model.confirmNewPassword).toBe('');
    		expect(scope.model.currentPassword).toBe('');
    	});
    });
});